/*
                             *******************
******************************* C SOURCE FILE *******************************
**                           *******************                           **
**                                                                         **
** project		: General Template                                         **
** filename		: JOIN.C                                                   **
** version		: 1.0                                                      **
** date			: December 31, 1986                                        **
**                                                                         **
*****************************************************************************
**                                                                         **
** Copyright (c) 2011, $pynarak                                            **
** All rights reserved.                                                    **
**                                                                         **
*****************************************************************************

VERSION HISTORY:
----------------

Version			: 1.0
Date 			: December 31, 1986
Revised by 		: $pynarak
Compiler        : GNU GCC
Description 	: Original version.
*/

#define _JOIN_C_SRC

/****************************************************************************/
/**                                                                        **/
/** MODULES USED                                                           **/
/**                                                                        **/
/****************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

/****************************************************************************/
/**                                                                        **/
/** DEFINITIONS AND MACROS                                                 **/
/**                                                                        **/
/****************************************************************************/

#define NUM_THREADS		8

/****************************************************************************/
/**                                                                        **/
/** TYPEDEFS AND STRUCTURES                                                **/
/**                                                                        **/
/****************************************************************************/

/****************************************************************************/
/**                                                                        **/
/** PROTOTYPES OF LOCAL FUNCTIONS                                          **/
/**                                                                        **/
/****************************************************************************/

void *thread_func(void *thread_argv);

/****************************************************************************/
/**                                                                        **/
/** EXPORTED VARIABLES                                                     **/
/**                                                                        **/
/****************************************************************************/

/****************************************************************************/
/**                                                                        **/
/** GLOBAL VARIABLES                                                       **/
/**                                                                        **/
/****************************************************************************/

pthread_mutex_t mutexVAR = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread_id[NUM_THREADS];

volatile int	counter = 0;

/****************************************************************************/
/**                                                                        **/
/** EXPORTED FUNCTIONS                                                     **/
/**                                                                        **/
/****************************************************************************/

/****************************************************************************/
/**                                                                        **/
/** LOCAL FUNCTIONS                                                        **/
/**                                                                        **/
/****************************************************************************/

int main (int argc, char *argv[])
{
	int i, j;

	for(i=0; i < NUM_THREADS; i++)
	{	
		pthread_create( &thread_id[i], NULL, thread_func, (void*)i);
	}

	for(j=0; j < (NUM_THREADS - 4); j++)
	{
		pthread_join( thread_id[j], NULL); 
	}

	/* Now that all threads are complete I can print the final result.     */
	/* Without the join I could be printing a value before all the threads */
	/* have been completed.                                                */

	printf("Final counter value: %d\r\n", counter);
	return 0;
}

void *thread_func(void *thread_argv)
{
	printf("Thread: %d is running.\r\n", (int)thread_argv);
	
	pthread_mutex_lock(&mutexVAR);
	sleep(1);
	counter++;
	printf("Thread: %d, counter value: %d\r\n", (int)thread_argv, counter);
	pthread_mutex_unlock(&mutexVAR);
}

/****************************************************************************/
/**                                                                        **/
/** EOF                                                                    **/
/**                                                                        **/
/****************************************************************************/
